0%

LevelDB源码解析(二)- Log文件格式

前言

题目的Log指的是文件格式,并不特使某个FileType。

因为LOG文件和Manifest文件都是使用的Log格式的文件进行记录的。

这里主要讲解的是LogWriter和LogReader两个类。

格式镇楼:

log文件格式

LogWriter

对于LogWriter而言,其实最重要的就是一个接口,Append一个Record:

1
2
3
4
public interface LogWriter {
// Writes a stream of chunks such that no chunk is split across a block boundary
void addRecord(Slice record, boolean force);
}

并且对于LogReader而言,它也是只有一个接口,读取一个Record:

1
2
3
public class LogReader {
public Slice readRecord();
}

既然所有的操作都是顺序写,顺序读,没有其他的操作,这里的Log文件格式就可以简单粗暴一点。

文件格式有三个概念要理清:

  1. Block,这里的Block固定是32K。读取文件时,每次读取一个Block大小,而写入时则需要按照Block的大小进行切分。

  2. Record:就是入参,这里的Record并没有限制大小,所有大小是不定的。

  3. Chunk:文件的写入单位是Chunk,Chunk也没有固定大小,但是不超过一个Block。

    Chunk的诞生缘由是因为Block固定是32K,而Record是不限制大小的。如果一个Record太大,超过了32K,则需要切分为多个Chunk,放入两个Block。

由于返回给上层的单位都是Record,所以我们需要知道下一个Record被分成了几个Chunk。

于是每次写入Chunk时,存入一个ChunkType。

  1. 如果Recod只被切分成一个Chunk,则ChunkType=FULL
  2. 如果Record被切分成多个Chunk,则第一个Chunk的Type=First,最后一个Chunk的Type=Last,中间的Chunk的Type=MIDDLE。

所以一个Chunk的具体格式如下:

log文件格式

对于读取而言,其实要做的也比较简单,先不断的去读取Block,然后迭代Block中的Chunk。

同时根据ChunkType的不同,不断迭代的读取Block,拼凑出一个完整的Block。